from datetime import datetime

from pydantic import field_validator
from sqlmodel import SQLModel, Field, Relationship,JSON


class User(SQLModel, table=True):
    """
    用户模型，对应数据库表：user
    SQLModel同时作为Pydantic模型和SQLAlchemy模型
    """
    # 主键，如果为None，则自动生成
    id: int | None = Field(default=None, primary_key=True)
    # 用户名，创建索引提高查询性能
    username: str = Field(index=True)
    # 邮箱，唯一约束且创建索引
    email: str = Field(unique=True, index=True, max_length=100)
    # 可选字段
    full_name: str | None = Field(default=None,max_length=100)
    # 时间字段
    created_time: datetime = Field(default_factory=datetime.now)

    # __table_args__ = {'extend_existing': True}




class Department(SQLModel, table=True):
    """
    部门模型，对应数据库表：department
    """
    id: int | None = Field(default=None, primary_key=True)
    name: str = Field(index=True,max_length=100)
    description: str | None = Field(default=None)
    created_time: datetime = Field(default_factory=datetime.now)
    # 一对多关系：一个部门可以有多个员工
    # back_populates指定Employee模型中的department字段
    employees: list["Employee"] = Relationship(back_populates="department")



class Employee(SQLModel, table=True):
    """
    员工模型，对应数据库表：employee
    """
    id: int | None = Field(default=None, primary_key=True)
    employee_id: str = Field(index=True,max_length=20)  # 员工工号
    first_name: str = Field(max_length=50)
    last_name: str = Field(max_length=50)
    email: str = Field(unique=True, index=True, max_length=100)
    phone: str | None = Field(default=None, max_length=20)
    hire_date: datetime = Field(default_factory=datetime.now)
    salary: float = Field(default=0.0)
    # 外键关联（这里并不是一定要有foreign_key, 主要用于在数据库层面建立外建约束，保证数据一致性）
    department_id: int | None = Field(default=None, index=True,foreign_key="department.id")

    # 定义一个名为department的关系属性，它表示当前员工所属部门。
    # Relationship类用于定义关系，back_populates参数表示当前关系所对应的属性在关联的模型中。
    department: Department | None = Relationship(back_populates="employees")


class ScheduledJob(SQLModel,table=True):
    """
    定时任务模型，对应数据库表：scheduled_job
    """
    __tablename__ = "scheduled_job"
    id: int | None = Field(default=None, primary_key=True)
    job_id: str = Field(index=True,max_length=100,unique=True)
    name: str = Field(max_length=200,nullable=False)
    task_function: str = Field(max_length=200,nullable=False)
    cron_expression: str = Field(max_length=200,nullable=True)
    interval_seconds: int | None = Field(default=None)
    job_args: list | None = Field(default=None, sa_type=JSON)
    job_kwargs: dict | None = Field(default=None, sa_type=JSON)
    is_active: bool = Field(default=True)
    created_time: datetime = Field(default_factory=datetime.now)
    updated_time: datetime = Field(default_factory=datetime.now)

    def __repr__(self):
        return f"<ScheduledJob(id={self.id}, job_id='{self.job_id}' name='{self.name}')>"


class JobExecutionHistory(SQLModel,table=True):
    """
    任务执行历史模型，对应数据库表：job_execution_history
    """
    __tablename__ = "job_execution_history"
    id: int | None = Field(default=None, primary_key=True)
    job_id: str = Field(index=True,max_length=100,foreign_key="scheduled_job.job_id",nullable=False)
    execution_time: datetime = Field(default_factory=datetime.now)
    status: str = Field(max_length=20,nullable=False)   # success, failed
    result: str | None = Field(default=None)
    error_message: str | None = Field(default=None)

